/* 
*  Copyright (C) 2009-2010 WCG Project
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/


#define TELEPORT_RADIUS				50
#define BLINK_COOLDOWN				2.0


new const Float:p_bash[5]				= {0.07, 0.09, 0.11, 0.13, 0.15}		// Bash
new const p_bok[5]						= {2, 4, 6, 8, 10}
new const p_holylight[5]				= {20, 25, 30, 35, 40}
new const p_holylight_manacost[5]		= {10, 12, 15, 18, 20}


PALADIN_InitSkills()
{
	SM_InitSkill( SKILL_HOJ, CLASS_PALADIN, SKILL_TYPE_TRAINABLE, sizeof(p_bash) )
	SM_InitSkill( SKILL_BOK, CLASS_PALADIN, SKILL_TYPE_TRAINABLE, 5 )
	SM_InitSkill( SKILL_DEVOTION, CLASS_PALADIN, SKILL_TYPE_TRAINABLE, 5 )
	SM_InitSkill( ABILITY_HOLYLIGHT, CLASS_PALADIN, SKILL_TYPE_ABILITY, 5, 10, 3 )
	SM_InitSkill( ULTIMATE_DIVINEPROTECTION, CLASS_PALADIN, SKILL_TYPE_ULTIMATE, 5, 10, 30 )
}

//------------------------------------
// PALADIN_TriggerAbility
//
//------------------------------------
public PALADIN_TriggerAbility( id, iSkillID )
{
	if( iSkillID == ABILITY_HOLYLIGHT )
	{
		if( PLAYER_CastSpell( id, ABILITY_HOLYLIGHT, CAST_NORMAL, _, _, _, CAST_SIMULATE ) ) 
		{
			new iSkillLevel = SM_GetSkillLevel( id, ABILITY_HOLYLIGHT )
			new iTargetID = UTIL_GetUserNearAim( id, PlayerInfo[id][PI_TeamID] )

			if( !IsValidUser(iTargetID) )
			{
				WCG_StatusText( id, 0, HUD_CASTING, "No target to heal found" )
				client_cmd( id, "spk %s", g_szSounds[SOUND_ERROR] )
				return
			}

			new param[3]
			param[0] = id
			param[1] = iTargetID
			param[2] = iSkillLevel
			
			PLAYER_CastSpell( id, ABILITY_HOLYLIGHT, CAST_NORMAL, "_SPELL_HolyLight", param, 3 )
		}
	}
}


//------------------------------------
// PALADIN_TriggerUltimate
//
//------------------------------------
public PALADIN_TriggerUltimate( id, iSkillID )
{
	if( iSkillID == ULTIMATE_DIVINEPROTECTION )
	{
		new param[1]
		param[0] = id
		PLAYER_CastSpell( id, ULTIMATE_DIVINEPROTECTION, CAST_NORMAL, "_SPELL_DivineProt", param, 1 )
	}
}




//------------------------------------
// PALADIN_SkillsDefensive
//
//------------------------------------
public PALADIN_SkillsDefensive( iAttacker, iVictim, &iDamage, iWeapon, iDamageType )
{
	if( PlayerBuffInfo[iVictim][BUFF_DivineProtection] )
	{
		if( iDamageType & DMG_SLASH )
			iDamage = min( iDamage * 10, 250 )
	
		else
			iDamage = floatround( float( iDamage ) * 0.70 )
	}
}



//------------------------------------
// PALADIN_SkillsOffensive
//
//------------------------------------
public PALADIN_SkillsOffensive( iAttacker, iVictim, iWeapon, iDamage, iDamageType )
{
	static iSkillLevel

	// Bash
	iSkillLevel = SM_GetSkillLevel( iAttacker, SKILL_HOJ )
	if( iSkillLevel > 0 )
	{
		if( random_float( 0.0, 1.0 ) <= p_bash[iSkillLevel-1] && !SHARED_IsPlayerSlowed( iVictim ) )
		{
			new param[2]
			param[0] = iAttacker
			param[1] = iVictim
			PLAYER_CastSpell( iAttacker, SKILL_HOJ, CAST_PASSIVE, "_SPELL_HoJ", param, 2 )
		}
	}
}






//------------------------------------
// PALADIN_DevotionAura
//
//------------------------------------
PALADIN_DevotionAura( id )
{
	if( !is_user_alive(id) )
		return

	new iSkillLevel = SM_GetSkillLevel( id, SKILL_DEVOTION )
	if( iSkillLevel <= 0 )
		return

	PlayerBuffInfo[id][BUFF_DevotionAura] = floatround( 40.0 * float(iSkillLevel) / float(g_SkillMaxLevel[SKILL_DEVOTION]) )

	new iHealth = PLAYER_GetMaxhealth( id )
	fm_set_user_health( id, iHealth )
}




//--------------------------------------------------------------------------------------------------------------------------
// Bash

#define BASH_GLOW_INTENSITY			100
#define BASH_HOLD_TIME				0.7

//------------------------------------
// _SPELL_HoJ
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//		param[1] = Victim ID
//------------------------------------
public _SPELL_HoJ( const param[] )
{
	new iCaster = param[0]
	new iVictim = param[1]

	if( !is_user_alive( iVictim ) )
		return

	if( !PLAYER_CheckMagicHit( iCaster, iVictim ) )
	{
		client_print( iCaster, print_chat, "Your Hammer of Justice was resisted by %s.", PlayerInfo[iVictim][PI_PlayerName] )
		client_print( iVictim, print_chat, "You resisted %s's Hammer of Justice.", PlayerInfo[iCaster][PI_PlayerName] )
		return
	}

	PlayerInfo[iVictim][PI_IsStunned] = true
	PLAYER_UpdateSpeed( iVictim )

	set_task( BASH_HOLD_TIME, "SHARED_ResetMaxSpeed", TASK_RESETSPEED + iVictim )

	emit_sound( iVictim, CHAN_STATIC, g_szSounds[SOUND_DECISIVESTRIKE], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )

	// Make the user glow!
	SHARED_Glow( iVictim, COLOR_RGB( BASH_GLOW_INTENSITY, BASH_GLOW_INTENSITY, BASH_GLOW_INTENSITY ) )

	EFFECT_ScreenShake( iVictim, 25.0, 1.5, 150.0 )
	EFFECT_ScreenFade( iVictim, 0.25, 0.25, COLOR_RGBA(255, 255, 255, BASH_GLOW_INTENSITY) )
}



//--------------------------------------------------------------------------------------------------------------------------
// Holy Light

public _SPELL_HolyLight( param[] )
{
	new iCasterID	= param[0]
	new iTargetID	= param[1]
	new iSkillLevel	= param[2]

	if( !is_user_alive( iCasterID ) || !is_user_alive( iTargetID ) )
		return

	PLAYER_Heal( iTargetID, p_holylight[iSkillLevel-1], iCasterID )
	SHARED_Glow( iTargetID, COLOR_RGB(72, 150, 0) )
	emit_sound( iTargetID, CHAN_STATIC, g_szSounds[SOUND_FLASH_HEAL], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )
}




//--------------------------------------------------------------------------------------------------------------------------
// Divine Protection

#define DIVINEPROT_DURATION  			3.0


//------------------------------------
// _SPELL_DivineProt
//
// PLAYER_CastSpell callback
//		param[0] = Caster ID
//------------------------------------
public _SPELL_DivineProt( const param[] )
{
	new id = param[0]

	if( !is_user_alive(id) )
		return

	PlayerInfo[id][PI_CanRender] = false
	PlayerBuffInfo[id][BUFF_DivineProtection] = true

	ULT_Icon( id, ICON_FLASH )

	if( !PlayerInfo[id][PI_IsPlantingDefusing] )
		Create_BarTime( id, floatround(DIVINEPROT_DURATION), 0 )
		
	emit_sound( id, CHAN_STATIC, g_szSounds[SOUND_VOODOO], VOL_NORM, ATTN_NORM, 0, PITCH_NORM )

	fm_set_user_rendering( id, kRenderFxGlowShell, 255, 255, 255, kRenderNormal, 18 )

	new vOrigin[3]
	get_user_origin( id, vOrigin )
	vOrigin[2] += 75

	EFFECT_EntityLight( id, _, _, COLOR_RGB(255,255,255), DIVINEPROT_DURATION )

	set_task( DIVINEPROT_DURATION, "_SPELL_RemoveDivineProt", TASK_ALIVE_EFFECT + id )
}



//------------------------------------
// _SPELL_RemoveDivineProt
//
//------------------------------------
public _SPELL_RemoveDivineProt( id )
{
	id = GetTaskID( id, TASK_ALIVE_EFFECT )

	if( !is_user_connected(id) )
		return

	SM_SetCooldown( id, ULTIMATE_DIVINEPROTECTION )

	PlayerInfo[id][PI_CanRender] = true
	PlayerBuffInfo[id][BUFF_DivineProtection] = false

	ULT_ClearIcons( id )

	PLAYER_UpdateInvisibility( id )
}




//------------------------------------
// PRIEST_BuffFortitude
//
//------------------------------------
public _PALADIN_BuffBoK()
{
	new iBufferID_T, iBufferID_CT, iSkillLevel_T, iSkillLevel_CT, iSkillLevel
	
	for( new id = 1 ; id <= GameInfo[GI_MaxPlayers] ; id++ )
	{
		if( !is_user_alive( id ) )
			continue
		
		if( PlayerInfo[id][PI_Class] != CLASS_PALADIN )
			continue
		
		iSkillLevel = SM_GetSkillLevel( id, SKILL_BOK )
		
		switch( PlayerInfo[id][PI_TeamID] )
		{
			case TEAM_T:
			{
				if( iSkillLevel > iSkillLevel_T )
					iBufferID_T = id
			}

			case TEAM_CT:
			{
				if( iSkillLevel > iSkillLevel_CT )
					iBufferID_CT = id
			}
		}
	}

	if( iBufferID_T )
		PALADIN_BoK( iBufferID_T )

	if( iBufferID_CT )
		PALADIN_BoK( iBufferID_CT )
}


//------------------------------------
// PALADIN_BoK
//
//------------------------------------
PALADIN_BoK( id )
{
	new iTargetID

	if( !is_user_alive(id) )
		return
	
	new iSkillLevel = SM_GetSkillLevel( id, SKILL_BOK )
	if( iSkillLevel <= 0 )
		return

	new iBonus = p_bok[iSkillLevel-1]

	new iTargetTeam = PlayerInfo[id][PI_TeamID]

	for( new i = 0 ; i < g_NumTeamPlayers[iTargetTeam] ; i++ )
	{
		iTargetID = g_SortedTeams[iTargetTeam][i]
		
		if( !is_user_alive(iTargetID) )
			continue

		if( PlayerBuffInfo[iTargetID][BUFF_BoK] != 0 )
			continue

		PlayerBuffInfo[iTargetID][BUFF_BoK] = iBonus

		InitAttributeEffects( iTargetID )

		fm_set_user_health( id, PLAYER_GetMaxhealth(id) )

		client_cmd( iTargetID, "speak %s", g_szSounds[SOUND_RESISTANCEAURA] )
		if( iTargetID == id )
			client_print( iTargetID, print_chat, "You gain Blessing of Kings Rank %d.", iSkillLevel )
		else
			client_print( iTargetID, print_chat, "%s casts Blessing of Kings Rank %d.", PlayerInfo[id][PI_PlayerName], iSkillLevel )
	}
}
